package com.xzq.spring;

import com.xzq.core.annotation.RpcService;
import com.xzq.pojo.ProviderService;
import com.xzq.register.Register;
import com.xzq.server.NettyServer;
import io.netty.channel.ChannelFuture;
import lombok.SneakyThrows;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.net.InetSocketAddress;
import java.util.Map;

/**
 * @Author xzq
 * @Description //TODO
 * @Date 2021/11/23 10:40
 * @Version 1.0.0
 **/
public class RpcNettyStater implements BeanFactoryAware {

    private Logger logger = LoggerFactory.getLogger(RpcNettyStater.class);
    @Autowired
    private NettyServer nettyServer;
    @Autowired
    private RpcProperties rpcProperties;
    @Autowired
    private Register register;


    @SneakyThrows
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        InetSocketAddress address = new InetSocketAddress(rpcProperties.getPort());
        ChannelFuture f = nettyServer.lister(address);
        if (f.isSuccess()) {
            if (beanFactory instanceof ListableBeanFactory) {
                ListableBeanFactory listableBeanFactory = (ListableBeanFactory) beanFactory;
                Map<String, Object> rpcBeans = listableBeanFactory.getBeansWithAnnotation(RpcService.class);
                for (Object o : rpcBeans.values()) {
                    Class<?>[] interfaces = o.getClass().getInterfaces();
                    String serviceName = interfaces[0].getName();
                    ProviderService providerService = new ProviderService(serviceName, address.getHostString(), rpcProperties.getPort());
                    //注册服务
                    logger.info("服务注册: {}", providerService);
                    register.register(providerService);
                }
            }
            f.channel().eventLoop().submit(() -> {
                try {
                    f.channel().closeFuture().sync();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
    }
}
